package com.wHitE.servlet;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.wHitE.utils.Result;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Properties;

/**
 * @author white_
 * @version 1.0
 * @project JavaWebCourse-Experiment4-plus
 * @description 发送邮箱验证码接口
 * @date 2023/11/17 20:32:16
 */

@WebServlet("/mail")
public class MailServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("邮箱验证码接口初始化...");
        super.init(config);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("邮箱验证码接口调用...");
        super.service(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取out对象
        PrintWriter out = resp.getWriter();

        // 初始化 object=>json 对象
        Gson gson = new Gson();

        String emailAccount = req.getParameter("email");

        //数据流获取信息
        StringBuilder stringBuilder = new StringBuilder();// 可变字符串构造对象
        BufferedReader reader = req.getReader();// 字符流读取对象
        char[] buf = new char[1024];// 创建字符数组(长度为请求体大小)
        int len;
        while ((len = reader.read(buf)) != -1) {// 追加字符串
            stringBuilder.append(buf, 0, len);
        }
        // 关闭字符输入流
        reader.close();
        // 将可变字符串转为字符串
        String str = stringBuilder.toString();

        if (emailAccount == null) {
            if (!str.isEmpty()) {
                //        // 以下方式通过创建类(属性与json对象的键值对应)接收请求的data参数值
                //        // 第一个参数需要json对象,第二个参数是对应的类
                //        Demo demo = gson.fromJson(str, Demo.class);
                //        System.out.println(demo.username + "," + demo.password);

                // 以下方式通过解析json字符串,获取参数值并转换为需要的数据类型
                // 实例化json解析对象
                JsonParser parser = new JsonParser();
                // 实例化json对象元素
                JsonElement element = parser.parse(str);
                // 获取并转换为所需的数据类型

                try {
                    emailAccount = element.getAsJsonObject().get("email").getAsString();
                } catch (Exception e) {
                    out.print(gson.toJson(Result.error("请求体参数错误")));
                    return;
                }
            } else {
                out.print(gson.toJson(Result.error("路径参数错误")));
                return;
            }
        }
        // 以下使用Java包下的mail原生方式
        Properties prop = new Properties();
        // 开启debug调试，以便在控制台查看
        // prop.setProperty("mail.debug", "true");
        // 设置邮件服务器主机名
        prop.setProperty("mail.host", "smtp.qq.com");
        // 发送服务器需要身份验证
        prop.setProperty("mail.smtp.auth", "true");
        // 发送邮件协议名称
        prop.setProperty("mail.transport.protocol", "smtp");
        try {
            // 开启SSL加密，否则会失败
            prop.put("mail.smtp.ssl.enable", "true");
            // 创建session
            Session session = Session.getInstance(prop);
            // 通过session得到transport对象
            Transport ts = session.getTransport();
            // 连接邮件服务器：邮箱类型，帐号，POP3/SMTP协议授权码 163使用：smtp.163.com，qq使用：smtp.qq.com
            ts.connect("smtp.qq.com", "1834893128", "niitoixgzvgtbhae");
            // 创建邮件
            Message message = createVerificationCode(resp, emailAccount, session);
            // 发送邮件
            ts.sendMessage(message, message.getAllRecipients());
            // 关闭transport对象
            ts.close();
            // 响应给前端
            resp.setContentType("application/json;charset=utf-8");
            out.print(gson.toJson(Result.success()));
        } catch (MessagingException e) {
            out.print(gson.toJson(Result.error("发送失败!请稍后重试")));
            throw new RuntimeException(e);
        }


        //        // 以下使用 apache 封装的 Java-mail 的 commons-email操作包 设置email发送更方便...
        //        // 创建邮件客户端
        //        HtmlEmail email = new HtmlEmail();
        //        // 指定邮件服务器地址
        //        email.setHostName("smtp.qq.com");
        //        // 指定服务器授权号和授权码
        //        email.setAuthentication("1834893128@qq.com", "niitoixgzvgtbhae");
        //        // 设置ssl加密
        //        email.setSSLOnConnect(true);
        //        // 设置调试模式
        //        email.setDebug(true);
        //        // 统一设置邮箱内容编码方式
        //        email.setCharset("utf-8");
        //
        //        // 指定发件人地址和名称
        //        try {
        //            email.setFrom("1834893128@qq.com", "白大人");
        //            // 指定收件人邮箱
        //            email.addTo("1834893128@qq.com");
        //            // 指定邮件主题
        //            email.setSubject("图书管理系统(JavaWeb-Servlet 开发版) 验证码");
        //            // 指定邮件的内容
        //            email.setHtmlMsg("<h1 style='text-align=center'>你的验证码为：" + createVerificationCode() + "</h1>");
        //            // 发送邮件
        //            email.send();
        //            // 响应给前端
        //            out.print(gson.toJson(Result.success()));
        //
        //        } catch (EmailException e) {
        //            e.printStackTrace();
        //        }
    }


    public MimeMessage createVerificationCode(HttpServletResponse resp, String emailAccount, Session session) {
        //  获取6为随机验证码
        String[] letters = new String[]{
                "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "a", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m",
                "A", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X", "C", "V", "B", "N", "M",
                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
        String stringBuilder = "";
        for (int i = 0; i < 6; i++) {
            stringBuilder = stringBuilder + letters[(int) Math.floor(Math.random() * letters.length)];
        }

        // 设置验证码过期
        Cookie cookie = new Cookie("email" + emailAccount.split("@")[0], stringBuilder);
        cookie.setMaxAge(2 * 60);
        resp.addCookie(cookie);

        // 创建邮件对象
        MimeMessage message = new MimeMessage(session);
        try {
            // 指明邮件的发件人
            message.setFrom(new InternetAddress("1834893128@qq.com", "白大人"));
            // 指明邮件的收件人，现在发件人和收件人是一样的，那就是自己给自己发
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(emailAccount));
            // 邮件的标题
            message.setSubject("图书管理系统(JavaWeb-Servlet 开发版) 验证码");
            // 邮件的文本内容
            message.setContent("<div style='text-align:center'>" +
                            "<h2>欢迎您注册 图书管理系统(JavaWeb-Servlet 开发版)</h2>" +
                            "<div>账号注册验证码为(两分钟内有效):<span style='color:#409EFF;text-decoration-line: underline;font-size:24px'>" + stringBuilder + "</span></div>" +
                            "<div>请勿回复此邮箱</div>" +
                            "</div>"
                    , "text/html;charset=UTF-8");
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        // 返回创建好的邮件对象
        return message;
    }

//    public String createVerificationCode() {
//        //  获取6为随机验证码
//        String[] letters = new String[]{
//                "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "a", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m",
//                "A", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X", "C", "V", "B", "N", "M",
//                "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
//        String stringBuilder = "";
//        for (int i = 0; i < 6; i++) {
//            stringBuilder = stringBuilder + letters[(int) Math.floor(Math.random() * letters.length)];
//        }
//
//        // 返回随即生成的验证码
//        return stringBuilder;
//    }

    @Override
    public void destroy() {
        System.out.println("邮箱验证码接口关闭...");
    }
}
